<?php

declare (strict_types=1);

namespace magein\pay\data;

use magein\pay\PayAccount;
use magein\pay\PayException;
use magein\pay\PayFactory;

class PayOrderData
{
    /**
     * 渠道id
     * @var string
     */
    private $channel_id = '';

    /**
     * 订单交易编号
     * 传递给第三方平台的，不能为空且唯一
     * @var string
     */
    private $pay_no = '';

    /**
     * 订单编号，真实的订单编号
     * @var string
     */
    private $order_no = '';

    /**
     * 实际金额
     * @var int
     */
    private $total_amount = 0;

    /**
     * 优惠金额
     * @var int
     */
    private $coupon_amount = 0;

    /**
     * 优惠信息
     * @var array|string
     */
    private $coupon_info = '';

    /**
     * 场景
     * @var int
     */
    private $scene = 1;

    /**
     * 订单标题
     * @var string
     */
    private $subject = '';

    /**
     * 订单附加信息。
     * 如果请求时传递了该参数，将在异步通知、对账单中原样返回，同时会在商户和用户的pc账单详情中作为交易描述展示
     * @var string
     */
    private $body = '';

    /**
     * 用户付款中途退出返回商户网站的地址
     * @var string
     */
    private $quit_url = '';

    /**
     * 支付完成跳转的页面
     * @var string
     */
    private $return_url = '';

    /**
     * 异步通知url
     * @var string
     */
    private $notify_url = '';

    /**
     * 交易平台
     * @var string
     */
    private $platform_id = '';

    /**
     * 应用ID
     * @var string
     */
    private $appid = '';

    /**
     * 收款账户
     * 1. 微信有appid和商户id
     * 2. 支付宝的商户id跟appid一致
     * @var string
     */
    private $merchant_id = '';

    /**
     * 平台的交易方式，app、H5等
     * @var string
     */
    private $trade_type = '';

    /**
     * 微信的open_id
     * @var string
     */
    private $open_id = '';

    /**
     * @var string
     */
    private $remark = '';

    /**
     * 用户id
     * @var string|integer
     */
    private $user_id = '';

    public function __construct($data)
    {
        $this->init($data);
    }

    /**
     * @param $data
     * @return $this
     */
    public function init($data): PayOrderData
    {
        $properties = [
            'channel_id',
            'platform_id',
            'order_no',
            'total_amount',
            'coupon_amount',
            'subject',
            'body',
            'user_id',
            'open_id',
            'remark',
            'return_url',
            'notify_url'
        ];

        foreach ($properties as $property) {
            $value = $data[$property] ?? '';
            if (in_array($property, ['total_amount', 'coupon_amount'])) {
                $value = intval($value);
            }
            $this->$property = $value;
        }

        return $this;
    }

    /**
     * @return string
     */
    public function getChannelId(): string
    {
        return $this->channel_id;
    }

    /**
     * @param string $channel_id
     * @return void
     */
    public function setChannelId(string $channel_id): void
    {
        $this->channel_id = $channel_id;
    }

    /**
     * @return string
     */
    public function getPayNo(): string
    {
        try {
            $pay_no = $this->pay_no ?: PayFactory::order()->getPayNo();
        } catch (PayException $exception) {
            $pay_no = uniqid();
        }

        return substr($pay_no, 0, 28);
    }

    /**
     * @param string $pay_no
     * @return void
     */
    public function setPayNo(string $pay_no): void
    {
        $this->pay_no = $pay_no;
    }

    public function getOrderNo(): string
    {
        return $this->order_no;
    }

    public function setOrderNo(string $order_no): void
    {
        $this->order_no = $order_no;
    }

    public function getTotalAmount(): int
    {
        return intval($this->total_amount);
    }

    public function setTotalAmount(int $total_amount): void
    {
        $this->total_amount = $total_amount;
    }

    public function getCouponAmount(): int
    {
        return intval($this->coupon_amount);
    }

    /**
     * @param int $coupon_amount
     * @return void
     */
    public function setCouponAmount(int $coupon_amount = 0): void
    {
        $this->coupon_amount = $coupon_amount;
    }

    /**
     * @return string
     */
    public function getCouponInfo(): string
    {
        return is_string($this->coupon_info) ? $this->coupon_info : '';
    }

    /**
     * @param string|array $coupon_info
     * @return void
     */
    public function setCouponInfo($coupon_info): void
    {
        if ($coupon_info && is_array($coupon_info)) {
            $coupon_info = json_encode($coupon_info);
        }

        $this->coupon_info = $coupon_info;
    }

    public function getScene(): int
    {
        return intval($this->scene);
    }

    public function setScene(int $scene): void
    {
        $this->scene = $scene;
    }

    public function getSubject(): string
    {
        return $this->subject;
    }

    public function setSubject(string $subject): void
    {
        $this->subject = $subject;
    }

    public function getBody(): string
    {
        return $this->body;
    }

    public function setBody(string $body): void
    {
        $this->body = $body;
    }

    public function getQuitUrl(): string
    {
        return $this->quit_url;
    }

    public function setQuitUrl(string $quit_url): void
    {
        $this->quit_url = $quit_url;
    }

    public function getReturnUrl(): string
    {
        return $this->return_url;
    }

    public function setReturnUrl(string $return_url): void
    {
        $this->return_url = $return_url;
    }

    public function getNotifyUrl(): string
    {
        return $this->notify_url;
    }

    public function setNotifyUrl(string $notify_url): void
    {
        $this->notify_url = $notify_url;
    }

    public function getPlatformId(): string
    {
        return $this->platform_id;
    }

    public function setPlatformId(string $platform_id): void
    {
        $this->platform_id = $platform_id;
    }

    public function getAppid(): string
    {
        return $this->appid;
    }

    public function setAppid(string $appid): void
    {
        $this->appid = $appid;
    }
    
    public function getMerchantId(): string
    {
        return $this->merchant_id;
    }

    public function setMerchantId(string $merchant_id): void
    {
        $this->merchant_id = $merchant_id;
    }

    public function getTradeType(): string
    {
        return $this->trade_type;
    }

    public function setTradeType(string $trade_type): void
    {
        $this->trade_type = $trade_type;
    }

    public function getOpenId(): string
    {
        return $this->open_id;
    }

    public function setOpenId(string $open_id): void
    {
        $this->open_id = $open_id;
    }

    /**
     * @return int|string
     */
    public function getUserId()
    {
        return $this->user_id;
    }

    /**
     * @param int|string $user_id
     */
    public function setUserId($user_id): void
    {
        $this->user_id = $user_id;
    }

    public function getRemark(): string
    {
        return $this->remark;
    }

    public function setRemark(string $remark)
    {
        $this->remark = $remark;
    }
}